#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>

//该类用于描述client的信息

#define Conv(addr) ((struct sockaddr*)&addr)

class InetAddr
{
private:
    void Net2Host()
    {
        _port = ntohs(_addr.sin_port);
        char ipbuffer[64];
        inet_ntop(AF_INET, &(_addr.sin_addr), ipbuffer, sizeof(ipbuffer));
        _ip = ipbuffer;
    }

    void  Host2Net()
    {
        memset(&_addr, 0, sizeof(_addr));
        _addr.sin_family = AF_INET;
        _addr.sin_port = htons(_port);
        inet_pton(AF_INET, _ip.c_str(), &(_addr.sin_addr));
    }
public:
    InetAddr(){};

    InetAddr(const struct sockaddr_in& addr)
        :_addr(addr)
    {
        Net2Host();
    }
    
    
    InetAddr(uint16_t port, const std::string& ip = "0.0.0.0")
        :_ip(ip)
        ,_port(port)
    {
        Host2Net();
    }

    void Init(const struct sockaddr_in& addr)//重设私有成员的值
    {
        _addr = addr;
        Net2Host();
    }

    std::string Ip()
    {
        return _ip;
    }
    uint16_t Port()
    {
        return _port;
    }

    struct sockaddr* Addr()
    {
        return Conv(_addr);
    }

    socklen_t Length()
    {
        return sizeof(_addr);
    }
    
    std::string ToString()
    {
        return _ip + "-" + std::to_string(_port);
    }

    bool operator==(const InetAddr& ia)
    {
        if(_ip == ia._ip && _port == ia._port)
        {
            return true;
        }//其实只要是同一个ip就能表示是一个人了
        return false;
    }
    

    ~InetAddr(){}
private:
    //网络风格地址
    struct sockaddr_in _addr;
    //主机风格地址
    std::string _ip;
    uint16_t _port;
};